package org.example.common.elasticsearch.utils;

import cn.hutool.core.util.ObjectUtil;
import org.dromara.easyes.core.biz.EsPageInfo;
import org.dromara.easyes.core.biz.SAPageInfo;
import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.example.common.core.utils.DateUtils;
import org.example.common.core.utils.page.Pager;
import org.example.common.core.utils.page.SearchParam;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;

public class EsSearchParamsHelper {

    /**
     * 是否加载 查询条件
     *
     * @param cnd
     * @param k
     * @param v
     * @return
     */
    private static boolean idLoadCnd(String cnd, String k, Object v) {
        return k.startsWith(cnd) && null != v && v.toString().length() > 0;
    }

    /**
     * 加载 搜索条件
     *
     * @param pager
     * @param wrapper
     */
    public static void loadSearchParam(Pager pager, LambdaEsQueryWrapper wrapper) {
        BoolQueryBuilder queryBuilder=QueryBuilders.boolQuery();
        EsSearchParamsHelper.loadSearchParam(pager,queryBuilder);
        SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
        searchSourceBuilder.query(queryBuilder);
        wrapper.setSearchSourceBuilder(searchSourceBuilder);
    }


    /**
     * 加载 搜索条件(浅分页)
     *
     * @param pager
     * @param wrapper
     * @param function
     */
    public static void loadSearchParam(Pager pager, LambdaEsQueryWrapper wrapper,BiFunction<Pager,LambdaEsQueryWrapper, EsPageInfo> function){
        EsSearchParamsHelper.loadSearchParam(pager,wrapper);
        EsPageInfo pageInfo=function.apply(pager,wrapper);
        pager.setRows(pageInfo.getList());
        pager.setTotal(pageInfo.getTotal());
        pager.setTotalPage(pageInfo.getPages());
    }


    /**
     *加载 搜索条件(SA分页)
     * @param pager
     * @param wrapper
     * @param function
     */
    public static void loadSearchParamSA(Pager pager, LambdaEsQueryWrapper wrapper,BiFunction<Pager,LambdaEsQueryWrapper, SAPageInfo> function){
        long pageNum= ObjectUtil.isNull(pager.getNextSearchAfter())?0:pager.getPageNum();
        EsSearchParamsHelper.loadSearchParam(pager,wrapper);
        SAPageInfo pageInfo=function.apply(pager,wrapper);
        pager.setRows(pageInfo.getList());
        pager.setTotal(pageInfo.getTotal());
        pager.setTotalPage(pageInfo.getPages());
        pager.setNextSearchAfter(pageInfo.getNextSearchAfter());
        if(pageNum!=pager.getTotalPage()) {
            pager.setPageNum(pageNum+1);
        }
    }


    /**
     * 加载 搜索条件
     *
     * @param pager
     * @param queryBuilder
     */
    public static void loadSearchParam(Pager pager, BoolQueryBuilder queryBuilder) {
        if (pager != null && pager.getSearchParams() != null && pager.getSearchParams().size() > 0) {
            Map<String, Object> searchParams = pager.getSearchParams();
            if (null != searchParams) {
                searchParams.forEach((k,v) -> {
                    if (idLoadCnd(SearchParam.SEARCH_EQ, k, v)) {
                        queryBuilder.filter(QueryBuilders.termQuery(k.split(SearchParam.SEARCH_EQ)[1], v));
                    } else if (idLoadCnd(SearchParam.SEARCH_GE, k, v)) {
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_GE)[1]).gte(v));
                    } else if (idLoadCnd(SearchParam.SEARCH_LE, k, v)) {
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_LE)[1]).lte(v));
                    }else if (idLoadCnd(SearchParam.SEARCH_RIGHT_LIKE, k, v)) {
                        queryBuilder.filter(QueryBuilders.matchPhrasePrefixQuery(k.split(SearchParam.SEARCH_RIGHT_LIKE)[1], v));
                    }else if (idLoadCnd(SearchParam.SEARCH_LIKE, k, v)) {
                        queryBuilder.filter(QueryBuilders.matchPhraseQuery(k.split(SearchParam.SEARCH_LIKE)[1], v));
                    } else if (idLoadCnd(SearchParam.SEARCH_DT_GE, k, v)) {//时间大于小于
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_DT_GE)[1]).gte(String.format("%s%s", v, " 00:00:00")));
                    } else if (idLoadCnd(SearchParam.SEARCH_DT_LE, k, v)) {//时间大于小于
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_DT_LE)[1]).lte(String.format("%s%s", v, " 23:59:59")));
                    } else if (idLoadCnd(SearchParam.SEARCH_IN, k, v)) {//包含
                        List data=(ArrayList) v;
                        queryBuilder.filter(QueryBuilders.termsQuery(k.split(SearchParam.SEARCH_IN)[1], data.toArray()));
                    }else if (idLoadCnd(SearchParam.SEARCH_NOTIN, k, v)) {//不包含
                        List data=(ArrayList) v;
                        queryBuilder.mustNot(QueryBuilders.termsQuery(k.split(SearchParam.SEARCH_NOTIN)[1],data.toArray()));
                    }
                    else if (idLoadCnd(SearchParam.SEARCH_DT_BETWEEN, k, v)) {//时间区间
                        List dts = (ArrayList) v;
                        dts.set(0, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.dateTime(DateUtils.YYYY_MM_DD, dts.get(0).toString())));
                        dts.set(1, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, DateUtils.dateTime(DateUtils.YYYY_MM_DD, dts.get(1).toString())));
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_DT_BETWEEN)[1]).gte( String.format("%s%s", dts.get(0), " 00:00:00")));
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_DT_BETWEEN)[1]).lte(String.format("%s%s", dts.get(1), " 23:59:59")));
                    }
                    else if (idLoadCnd(SearchParam.SEARCH_DTS_BETWEEN, k, v)) {//时间区间
                        List dts = (ArrayList) v;
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_DTS_BETWEEN)[1]).gte(dts.get(0).toString()));
                        queryBuilder.filter(QueryBuilders.rangeQuery(k.split(SearchParam.SEARCH_DTS_BETWEEN)[1]).lte(dts.get(1).toString()));
                    }
                });
            }
        }
    }

}

